package com.example.baiguangsystem.constroller;

import com.example.baiguangsystem.entity.Book;
import com.example.baiguangsystem.entity.Section;
import com.example.baiguangsystem.service.BookService;
import com.example.baiguangsystem.service.SectionService;
import com.example.baiguangsystem.vo.ResultType;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;

/**
 * 书本控制器类
 *
 * @Author: 27641
 * @ProjectName: BaiGuangSystem
 * @Date: 2022/02/04/16:32
 * @noinspection SpellCheckingInspection
 */
@Controller
@RequestMapping("/book")
public class BookController {

    /**
     * 上传文件保存路径
     */
    private static final String UPLOADIN_FILE_PATH = "E:\\垃圾文件夹\\将夜\\";

    /**
     * 注入依赖
     */
    @Autowired
    private BookService bookService;
    @Autowired
    private SectionService sectionService;


    /**
     * 根据书本Id查找书本信息
     *
     * @param bookId 需要查找的书本Id
     * @return 查找结果
     */
    @GetMapping("/findBookById/{bookId}")
    @ResponseBody
    public ResultType findBookById(@PathVariable Integer bookId) {
        Book book = this.bookService.findBookById(bookId);
        if (book != null) {
            return ResultType.success("查找成功！", book);
        }
        return ResultType.fail("查找失败，可能是没有该数据!");
    }

    /**
     * 根据书本名字查找书本信息
     *
     * @param bookName 需要查找的书本名字
     * @return 查找结果
     */
    @GetMapping("/findBookByName/{bookName}")
    @ResponseBody
    public ResultType findBookByName(@PathVariable String bookName) {
        Book bookByName = this.bookService.findBookByName(bookName);
        if (bookByName != null) {
            return ResultType.success("查找成功！", bookByName);
        }
        return ResultType.fail("查找失败，可能是没有该数据!");
    }


    /**
     * 查找书本的所有章节名字
     *
     * @param bookId 需要查找的书本Id
     * @return 查找结果
     */
    @GetMapping("/findBookAllSections/{bookId}")
    @ResponseBody
    public ResultType findBookAllSections(@PathVariable Integer bookId) {
        List<Section> sectionList = this.sectionService.findSectioAllByBookId(bookId);
        if (sectionList != null) {
            return ResultType.success("查找成功！", sectionList);
        }
        return ResultType.fail("查找失败，可能是没有该数据！");
    }

    /**
     * 新增章节给指定书本表Id的书本
     *
     * @param newSection 新增章节
     * @param bookId     新增章节所属书本表Id
     * @return ResultType 操作结果
     */
    @PostMapping("/newAddSectionByBookId/{bookId}")
    @ResponseBody
    public ResultType newAddSectionByBookId(@RequestBody Section newSection, @PathVariable Integer bookId) {
        this.sectionService.newAddSectionByBookId(newSection, bookId);
        return ResultType.success("新增章节成功!", newSection);
    }


    /**
     * 根据章节Id删除章节
     *
     * @param sectionId 需要删除的章节Id
     * @return 操作结果
     */
    @GetMapping("/deleteSectionByBookId/{sectionId}")
    @ResponseBody
    public ResultType deleteSectionByBookId(@PathVariable Integer sectionId) {
        Section section = this.sectionService.deleteSectionByBookId(sectionId);
        if (section != null) {
            return ResultType.success("删除章节成功！", section);
        }
        return ResultType.success("删除章节失败！");
    }

    /**
     * 根据章节Id下载章节(目前取消了返回下载状态的封装信息对象，因为会导致多次使用response响应对象，
     * 引发异常)
     *
     * @param sectionId 需要下载的章节Id
     * @param response  响应对象
     */
    @SneakyThrows
    @GetMapping("/downloadSectionById/{sectionId}")
    @ResponseBody
    public void sectionDownloadById(@PathVariable Integer sectionId, HttpServletResponse response) {
        /*获取章节信息*/
        Section section = this.sectionService.findSectionById(sectionId);
        this.bookService.downloadSection(section, response);
    }


    /**
     * 指定书本Id，下载该书本的全部章节(目前取消了返回下载状态的封装信息对象，
     * 因为会导致多次使用response响应对象，引发异常)
     *
     * @param bookId   需要下载的书本Id
     * @param response 响应对象
     */
    @GetMapping("/downloadBookAllSectionById/{bookId}")
    @ResponseBody
    public void downloadAllSectionByBookId(@PathVariable Integer bookId, HttpServletResponse response) {
        /*查找指定书本的所有章节信息*/
        List<Section> sectioAllByBookId = this.sectionService.findSectioAllByBookId(bookId);
        this.bookService.downloadAllSection(sectioAllByBookId, response, bookId);
    }

    /**
     * 上传章节给指定的书本Id类（单文件上传）
     *
     * @param multipartFile 客户端上传的文件
     * @param bookId        指定上传章节给目标书的Id
     */
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/uploading/{bookId}")
    @ResponseBody
    public ResultType uploadingSectionByBookId(@RequestBody MultipartFile multipartFile,
                                               @PathVariable Integer bookId) {
        if (!multipartFile.isEmpty()) {
            InputStream inputStream = multipartFile.getInputStream();
            File file = new File(UPLOADIN_FILE_PATH + multipartFile.getOriginalFilename());
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            byte[] bytes = new byte[1024];
            int len = -1;
            while (-1 != (len = inputStream.read(bytes))) {
                fileOutputStream.write(bytes, 0, len);
            }
            /*保存好上传文件之后存储进去数据库之中*/
            Section section = new Section();
            section.setSectionName(file.getName().split(".txt")[0]);
            section.setSectionPath(file.getAbsolutePath());
            this.sectionService.newAddSectionByBookId(section, bookId);
            return ResultType.success("上传文件成功！");
        }
        return ResultType.fail("请上传文件！");
    }

    /**
     * 上传多文件给指定书本类（多文件上传）
     *
     * @param multipartFiles
     * @param bookId
     * @return
     */
    @SneakyThrows
    @PostMapping("/uploadAllSectionByBookId/{bookId}")
    @ResponseBody
    public ResultType uploadingMoreSectionByBookId(@RequestBody MultipartFile[] multipartFiles,
                                                   @PathVariable Integer bookId) {

        if (multipartFiles != null && multipartFiles.length >= 1) {
            for (MultipartFile multipartFile : multipartFiles) {
                String filename = multipartFile.getOriginalFilename();
                File file = new File(UPLOADIN_FILE_PATH + filename);
                InputStream inputStream = multipartFile.getInputStream();
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                byte[] bytes = new byte[1024];
                int len = -1;
                while (-1 != (len = inputStream.read(bytes))) {
                    fileOutputStream.write(bytes, 0, len);
                }
                fileOutputStream.flush();
                fileOutputStream.close();
                inputStream.close();
                /*将保存好的文件放入数据库之中*/
                Section section = new Section();
                section.setSectionName(multipartFile.getOriginalFilename().split(".txt")[0]);
                section.setSectionPath(file.getAbsolutePath());
                this.sectionService.newAddSectionByBookId(section, bookId);
            }
            return ResultType.success("上传成功！");
        }
        return ResultType.fail("请上传至少一个文件!");
    }

}
